package com.sir.tao.carhire.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.sir.tao.carhire.common.CommonResult;
import com.sir.tao.carhire.entity.table.CarEntity;
import com.sir.tao.carhire.entity.table.CarTypeEntity;
import com.sir.tao.carhire.entity.table.ContractEntity;
import com.sir.tao.carhire.entity.vo.CarContinueRentVo;
import com.sir.tao.carhire.entity.vo.CarRetireVo;
import com.sir.tao.carhire.service.CarService;
import com.sir.tao.carhire.service.CarTypeService;
import com.sir.tao.carhire.service.ContractService;
import com.sir.tao.carhire.util.MinioUtil;
import com.sir.tao.carhire.util.PageUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author tao
 * @data 2021/12/6 10:48
 * @description: 管理员登录接口
 */
@RestController
@Api(tags = "租凭业务接口")
@RequestMapping("/business")
public class BusinessController {


    @Resource
    private CarTypeService carTypeService;
    @Resource
    private CarService carService;
    @Resource
    private ContractService contractService;
    @Resource
    private MinioUtil minioUtil;

    /**
     * 获取所有的汽车类型
     * @return 汽车所有类型
     */
    @GetMapping("/carType/list")
    @ApiOperation("获取所有的汽车类型")
    @ApiImplicitParam(name = "获取所有的汽车类型", value = "获取所有的汽车类型")
    public CommonResult<?> getAllCarType(@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
                                         @RequestParam(name="pageSize", defaultValue="9999") Integer pageSize){
        List<CarTypeEntity> list = carTypeService.list();
        PageUtil page = PageUtil.doPage(pageNo,pageSize, list);
        return CommonResult.success(page);
    }

    /**
     * 根据汽车类型获取所有的汽车
     * @return 根据汽车类型获取所有的汽车
     */
    @GetMapping("/car/list")
    @ApiOperation("根据汽车类型获取所有的汽车")
    @ApiImplicitParam(name = "根据汽车类型获取所有的汽车", value = "根据汽车类型获取所有的汽车")
    public CommonResult<?> getAllCar(String carTypeId,
                                     @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
                                     @RequestParam(name="pageSize", defaultValue="10") Integer pageSize){
        LambdaQueryWrapper<CarEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(CarEntity::getCarTypeId,carTypeId);
        List<CarEntity> list = carService.list(lambdaQueryWrapper);
        PageUtil page = PageUtil.doPage(pageNo,pageSize, list);
        return CommonResult.success(page);
    }

    /**
     * 车辆预约
     *
     * @param contractEntity 合同实体
     * @return 车辆预约
     */
    @PostMapping("/contract/add")
    @ApiOperation("车辆预约")
    @ApiImplicitParam(name = "车辆预约", value = "车辆预约")
    public CommonResult<?> addContract(@RequestBody ContractEntity contractEntity) {

        CarEntity carEntity = carService.getById(contractEntity.getCarId());
        if (Objects.isNull(carEntity) || carEntity.getIsRent()==1){
            return CommonResult.fail("该车已经租用或不存在");
        }
        contractEntity.setSignTime(new Date());
        contractEntity.setCreateTime(new Date());
        boolean i = contractService.save(contractEntity);
        if (i) {
            carEntity.setIsRent(1);
            carService.saveOrUpdate(carEntity);
            return CommonResult.success();
        } else {
            return CommonResult.fail("新增合同失败");
        }
    }

    /**
     * 归还汽车
     * @return 根据汽车类型获取所有的汽车
     */
    @PostMapping("/car/retire")
    @ApiOperation("归还汽车")
    @ApiImplicitParam(name = "归还汽车", value = "归还汽车")
    public CommonResult<?> carRetire(@RequestBody CarRetireVo carRetireVo){
        ContractEntity contractEntity = contractService.getById(carRetireVo.getContractId());
        if (contractEntity.getIsReceive()!=1){
            return CommonResult.fail("需要先领取汽车");
        }
        //合同完成
        contractService.contractSuccess(carRetireVo.getContractId());
        //汽车租用状态改为未租用
        carService.update(new LambdaUpdateWrapper<CarEntity>()
                .eq(CarEntity::getId,carRetireVo.getCarId())
                .set(CarEntity::getIsRent,0)
        );
        return CommonResult.success();
    }

    /**
     * 领取汽车
     * @return 是否成功
     */
    @PostMapping("/receive/car")
    @ApiOperation("领取汽车")
    @ApiImplicitParam(name = "领取汽车", value = "领取汽车")
    public CommonResult<?> carContinueRent(String contractId){
        ContractEntity contractEntity = contractService.getOne(new LambdaQueryWrapper<ContractEntity>()
                .eq(ContractEntity::getId,contractId)
        );

        if (Objects.isNull(contractEntity)){
            return CommonResult.fail("数据错误，请联系管理员");
        }
        if (contractEntity.getStatus()!=2 || contractEntity.getIsExamine()!=1){
            return CommonResult.fail("只有审核完成才能领取");
        }
        contractEntity.setIsReceive(1);
        boolean i = contractService.saveOrUpdate(contractEntity);
        if (i){
            return CommonResult.success();
        }else {
            return CommonResult.fail("领取失败");
        }
    }
    /**
     * 续租汽车
     * @return 是否成功
     */
    @PostMapping("/car/continue/rent")
    @ApiOperation("续租汽车")
    @ApiImplicitParam(name = "续租汽车", value = "续租汽车")
    public CommonResult<?> carContinueRent(@RequestBody CarContinueRentVo carContinueRentVo){
        ContractEntity contractEntity = contractService.getById(carContinueRentVo.getContractId());
        if (Objects.isNull(contractEntity) || contractEntity.getStatus()!=2){
            return CommonResult.fail("只有生效的合同才能归还车辆");
        }
        //续租1.原合同完成
        contractService.contractSuccess(carContinueRentVo.getContractId());
        //续租2.生成新的合同
        ContractEntity newContract = contractEntityToNeW(contractEntity);
        newContract.setStatus(2);
        newContract.setSignTime(new Date());
        newContract.setTakeTime(contractEntity.getEndTime());
        newContract.setEndTime(carContinueRentVo.getEndTime());
        newContract.setIsReceive(1);
        boolean m = contractService.save(newContract);
        if (m){
            return CommonResult.success();
        }else {
            return CommonResult.fail("续租失败");
        }
    }
    private ContractEntity contractEntityToNeW(ContractEntity contractEntity){
        ContractEntity newContract = new ContractEntity();
        newContract.setFirstParty(contractEntity.getFirstParty());
        newContract.setPartyB(contractEntity.getPartyB());
        newContract.setContent(contractEntity.getContent());
        newContract.setSignTime(contractEntity.getSignTime());
        newContract.setTakeTime(contractEntity.getTakeTime());
        newContract.setEndTime(contractEntity.getEndTime());
        newContract.setStatus(contractEntity.getStatus());
        newContract.setFlat(contractEntity.getFlat());
        newContract.setIsExamine(contractEntity.getIsExamine());
        newContract.setCarId(contractEntity.getCarId());
        newContract.setUserId(contractEntity.getUserId());
        return newContract;
    }
    /**
     * 查看我的合同列表
     * @return 查看我的合同列表
     */
    @GetMapping("/contract/my")
    @ApiOperation("查看我的合同列表")
    @ApiImplicitParam(name = "查看我的合同列表", value = "查看我的合同列表")
    public CommonResult<?> contractMy(
            @RequestParam String userId,
            @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
            @RequestParam(name="pageSize", defaultValue="10") Integer pageSize){
        List<ContractEntity> list = contractService.list(new LambdaQueryWrapper<ContractEntity>()
                .eq(ContractEntity::getUserId,userId))
                .stream().sorted(Comparator.comparing(ContractEntity::getSignTime)).collect(Collectors.toList());
        PageUtil page = PageUtil.doPage(pageNo,pageSize, list);
        return CommonResult.success(page);
    }

    @ApiOperation("上传客户端图片")
    @ApiImplicitParam(name = "上传客户端图片", value = "上传客户端图片  ")
    @PostMapping("/upload")
    public CommonResult<?> uploadPhoto(@RequestParam("file") MultipartFile file) throws IOException {
        try {
            int length = file.getBytes().length;
            if (length > 5 * 1024 * 1024){
                return CommonResult.fail("图片不得超过5M");
            }
        } catch (IOException e) {
            e.printStackTrace();
            return CommonResult.fail("上传文件失败");
        }
        long time1 = System.currentTimeMillis();
        int begin = Objects.requireNonNull(file.getOriginalFilename()).indexOf(".");
        int last = file.getOriginalFilename().length();
        //获得文件后缀名
        String a = file.getOriginalFilename().substring(begin, last);
        String fileName = file.getName()+time1+a;
        boolean upload = minioUtil.putObject("car-hire", fileName, file.getInputStream());
        if (upload){
            return CommonResult.success(fileName);
        }else {
            return CommonResult.fail("上传失败");
        }
    }

    @ApiOperation("下载图片")
    @ApiImplicitParam(name = "下载图片", value = "下载图片  ")
    @GetMapping("/download")
    public void downloadPhoto(String fileName, HttpServletResponse response) throws IOException {
        InputStream in = minioUtil.getObject("car-hire",fileName);

        OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
        //创建存放文件内容的数组
        byte[] buff =new byte[1024];
        //所读取的内容使用n来接收
        int n;
        //当没有读取完时,继续读取,循环
        while((n=in.read(buff))!=-1){
            //将字节数组的数据全部写入到输出流中
            outputStream.write(buff,0,n);
        }
        //强制将缓存区的数据进行输出
        outputStream.flush();
        //关流
        outputStream.close();
        in.close();
    }
}
